import os
from rdflib import Namespace, BNode, Literal, RDF, URIRef
from semprog.pysesame import connection
import cherrypy
from mako.lookup import TemplateLookup
import urllib
from simplejson import dumps
from classes import classes

user_cfg = os.path.expanduser("~/cherrypy.cfg")
if os.path.exists(user_cfg):
    cherrypy_cfg = user_cfg
elif os.path.exists("cherrypy.cfg"):
    cherrypy_cfg = "cherrypy.cfg"
else:
    cherrypy_cfg = None
if cherrypy_cfg:
    cherrypy.config.update(cherrypy_cfg)
else:
    cherrypy.config.update({'server.socket_port':8000})

url=cherrypy.config.setdefault('sesame.url','http://localhost:8080')
url+='/openrdf-sesame/'
lookup = TemplateLookup(directories=['templates'],
                        output_encoding='utf-8',encoding_errors='replace',
                        input_encoding='utf-8')
con=connection(url)
repository=cherrypy.config.setdefault('sesame.repository','3account')
con.use_repository(repository)
OFX = Namespace("http://www.w3.org/2000/10/swap/pim/ofx#")
OFXH = Namespace("http://www.w3.org/2000/10/swap/pim/ofx-headers#")
XSD = Namespace("http://www.w3.org/2001/XMLSchema#")
A3 = Namespace("http://code.google.com/p/3account/wiki/Schema#")
con.addnamespace('ofx',OFX)
con.addnamespace('ofxh',OFXH)
con.addnamespace('xsd',XSD)
con.addnamespace('a3',A3)

def lst(l):
    """make sure something is a list"""
    if isinstance(l,list):
        return l
    else:
        return [l]
    
def row2class(items,row,typ):
    c=classes[typ]
    row2dict(items,row,c['key'],c['key']+c['mandatory']+c['optional'],typ)

def row2dict(objDict,row,idtag,tags,typ=None):
    """ Build objects out of flat-lines!
row is a dict with tag:value pairs.
The value in row is either a list of literals (str,float) or a dict of the form {'value':value,'datatype':'xsd:...'}.

The function searches for an object in row and if found adds it to objDict.
The key to the object in objDict is a str of a single value or str of a list of multiple values.
In this way an object with a simple key is easy to access.

The value(s) for the key are taken from the values assigned in row to the tag(s) defined by idtag.
If not all idtag(s) are found in row then the object is not "in" the row.

An object is dict stored as a value in objDict.
The object may have attributes which are tag:[value,...] pairs were value (str,float) are taken from the row
and the tag are taken from tags list.
objDict={...
   str(row[idtag[0]]):{'label':key, 'type':typ, tags[0]:[..., row[tags[0]], ...}
or
   str([row[idtag[0]], row[idtag[1]],...]):{'label':key, 'type':typ, tags[0]:[..., row[tags[0]], ...}
...}
Only unique values are stored, and if the tag in tags is prefixed with '+' the value (float) is added
"""
    idtag = lst(idtag)
    if any(t not in row for t in idtag): return
    nrow =dict((t,[v['value']] if isinstance(v,dict) else v) for t,v in row.iteritems())
    key=str(nrow[idtag[0]][0] if len(idtag)==1
            else [nrow[t][0] for t in idtag])
    if key not in objDict: objDict[key] = {'label':key}
    if typ: objDict[key]['type']=typ
    for tag in tags:
        add=False
        if tag.startswith('+'):
            tag=tag[1:]
            add=True
        if tag not in row: continue
        for v in nrow[tag]:
            if (isinstance(row[tag],dict) and
                row[tag].get('datatype','') == str(XSD.term('decimal'))):
                v = float(v)
            if tag not in objDict[key]:
                objDict[key][tag]=[0.] if add else []
            if add:
                objDict[key][tag][0]+=float(v)
            elif v not in objDict[key][tag]:
                objDict[key][tag].append(v)

from htmlentitydefs import codepoint2name
def htmlentities(u):
    result = []
    for c in u:
        if ord(c) in codepoint2name:
            result.append('&%s;' % codepoint2name[ord(c)])
        elif c==' ':
            result.append('&nbsp;')
        else:
            result.append(c)
    return ''.join(result)

def printCleanup(trans):
    """ cleanup for printing """
    if not isinstance(trans,list): trans=[trans]
    for tran in trans:
        for tag in tran.iterkeys():
            tran[tag] = [v[v.rfind("#")+1:] if isinstance(v,basestring) else v for v in tran[tag]]
            tran[tag] = [htmlentities("%.2f"%v if isinstance(v,float) else v) for v in tran[tag]]
